<?php
/**
 * static class for errorhandling and loggin
 *
 * @since 2010-06-02
 * @author Daniel Niedergesäß <daniel.niedergesaess@googlemail.com>
 * @version $Id$
 */

final class Core_Errorhandler{

    private static $ERRORS = 0;

    private static $WARNINGS = 0;

    /**
     * private constructor cause static class
     */
    private function __construct() { }

    /**
     * init errorhandler
     */
    public static function init() {
        set_error_handler(array('Core_Errorhandler', 'handleError'));
        self::$ERRORS = E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR;
        self::$WARNINGS = E_CORE_WARNING | E_COMPILE_WARNING | E_USER_WARNING | E_USER_NOTICE | E_STRICT | E_NOTICE ^E_WARNING;
    }

    /**
     * Method to handle the error
     *
     * @param Exception $e Exception
     * @return Boolean Returns true if successful
     */
    public static function handleError($errno, $errstr, $errfile, $errline) {
        if (defined('CONFIG_ERROR_LOG_ENABLED') && CONFIG_ERROR_LOG_ENABLED === true){
            if((self::$ERRORS & $errno) == $errno) {
                restore_error_handler();
                throw new Core_Exception("PHP-Error: $errstr", $errno);
                return;
            }
            if(! (self::$WARNINGS & $errno) == $errno) {
                return;
            }
		$log = '';
		$log .= "\n###############################################################################\n";
		$log .= '# '.strftime('%Y-%m-%d %H:%M:%S')."                                                         #\n";
		$log .= "###############################################################################\n";
		$log .= "Aufgetretene Warnung ($errno)\n";
		$log .= 'Nachricht: ';
		$log .= str_replace("\n", "\n           ", $errstr)."\n";
		$log .= 'Remote Adresse: '.$_SERVER['REMOTE_ADDR']."\n";


		$log .= "\n-------------------------------------------------------------------------------\n";
		$log .= "Backtrace\n";
		$log .= self::formatTrace(debug_backtrace());
		$log .= "\n-------------------------------------------------------------------------------\n";
		$log .= "Request\n";
		$log .= "\n\n\n\n";
                if (defined('CONFIG_ERROR_LOG_FILE') && $fp = fopen(CONFIG_ERROR_LOG_FILE, 'a+')){
                    fwrite($fp, $log);
                    fclose($fp);
                }
	}
    }

    /**
     *
     * @param array $trace
     * @return string trace as string
     */
    public static function formatTrace($trace) {
        $trace_str = '';
        $steps = count($trace)-1;
        foreach($trace AS $k => $step) {
            if(($k == $steps) || (isset($step['type']) && ($step['class'] == 'Core_Errorhandler' || $step['function'] == 'handleError') || (isset($step['file']) === false))) {
                continue;
            }
            $trace_str .= "\t".str_replace(CONFIG_PATH_SYSTEM,'',$step['file']).'::'.$step['line']. ' # ';
            if(isset($step['type'])) {
                $trace_str .= $step['class'].$step['type'].$step['function'];
            } else {
                $trace_str .= $step['function'];
            }

            $trace_str .= '(';
            if (isset($step['args']) && is_array($step['args'])){
                foreach($step['args'] AS $i => $arg) {
                    if($i != 0) $trace_str .= ', ';
                    switch(gettype($arg)) {
                        case 'boolean': $trace_str .= ($arg?'true':false); break;
                        case 'NULL': $trace_str .= 'NULL'; break;
                        case 'integer':
                        case 'double': $trace_str .= $arg; break;
                        case 'object': $trace_str .= get_class($arg); break;
                        case 'string': {
                            $value = str_replace(array("\n", "\t", '  '), '', print_r($arg, true));
                            if(strlen($value) < 50) {
                                $trace_str .= '"'.$value.'"';
                            } else {
                                $trace_str .= '"'.substr($value, 0, 50).' ..."';
                            }
                            break;
                        }
                        default: {
                            $trace_str .= gettype($arg);
                            if(count($arg)) {
                                $trace_str .= '('.@count($arg).')';
                            }
                        }
                    }
                }
            }
            $trace_str .= ')';
            $trace_str .= "\n";
        }
        return $trace_str;
    }
}
?>